package com.geralt.im.server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

import com.geralt.im.commands.impl.ExitCommand;
import com.geralt.im.controller.Controller;
import com.geralt.im.jsonparser.IjsonParser;
import com.geralt.im.jsonparser.impl.RequestJsonParser;
import com.geralt.im.parse.impl.RqParser;
import com.geralt.im.protocol.Request;
import com.geralt.im.protocol.Response;
import com.geralt.im.tool.JsonTool;

public class JsonClientSession extends ClientSession implements Runnable {

	// private Socket socket;

	private InputStream is = null;
	private BufferedReader ois = null;
	private OutputStream os = null;
	private BufferedWriter oos = null;

	// private boolean isRun;

	public JsonClientSession(Socket socket) {
		super(socket);

		try {
			is = socket.getInputStream();
			ois = new BufferedReader(new InputStreamReader(is));
			os = socket.getOutputStream();
			oos = new BufferedWriter(new OutputStreamWriter(os));
		} catch (Exception e) {
//			e.printStackTrace();
			closeSocket();
		}
	}

	@Override
	public void run() {
		isRun = true;
		try {
			while (isRun) {
				String rqString = ois.readLine();
				if(isRun==false){
					continue;
				}
				System.out.println(rqString);			/////////////////
				IjsonParser jp = new RequestJsonParser();
				Request rq = (Request) jp.parse(rqString);
				Controller controller = Controller.getInstance();
				controller.excute(rq, this);
			}
		} catch (Exception e) {
			
			for (String id : IMServer.map.keySet()) {
				if (IMServer.map.get(id) == this) {
					Map<String,Object> parameter = new HashMap<String,Object>();
					parameter.put("EXIT",id);
					Request request = new Request();
					request.setType("EXIT");
					request.setParameter(parameter);
					Controller.getInstance().excute(request, this);
					
				}
			}
		}
		closeSocket();
	}

	public void closeSocket() {
		try {
			is.close();
			ois.close();
			if (os == null) {
				os.close();
				oos.close();
			}
			socket.close();
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

	@Override
	public void close() {
		// TODO Auto-generated method stub
		try {
			is.close();
			ois.close();
			if (os == null) {
				os.close();
				oos.close();
			}
			socket.close();
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

	@Override
	public void send(Object response) {
		try {
			if (!socket.isClosed()) {
				JsonTool jt = JsonTool.getInstance();
				String sendString = jt.objectToString(response);
				System.out.println(response.toString());		////////////////////
				oos.write(sendString+"\n");
				oos.flush();
			}
		} catch (Exception e) {
			for (String id : IMServer.map.keySet()) {
				if (IMServer.map.get(id) == this) {
					IMServer.map.remove(id);
				}
			}
			closeSocket();
		}
	}

}
